//
//  HttpManager.m
//  CoolFlow
//
//  Created by wulanzhou on 16/6/3.
//  Copyright © 2016年 wulanzhou. All rights reserved.
//

#import "HttpManager.h"
#import "AFNetworking.h"
#import "HttpServerArgs.h"
#import "GlobalNetDefine.h"
#import "SystemUser.h"

// 请求block
typedef void (^RequestBlock)(void);

extern BOOL isLoging;

@interface HttpManager()
@property (nonatomic, strong) AFHTTPSessionManager  *manager;
@property (nonatomic, strong) NSMutableArray        *arrayRequest;
@property (nonatomic, strong) NSMutableArray        *arrayHttpArgs;
@end

@implementation HttpManager

+ (HttpManager *)shareInstance {
    static dispatch_once_t  onceToken;
    static HttpManager * sSharedInstance;
    
    dispatch_once(&onceToken, ^{
        sSharedInstance = [[HttpManager alloc] init];
    });
    return sSharedInstance;
}

- (id)init {
    self = [super init];
    if (self) {
        self.arrayRequest = [NSMutableArray array];
        self.arrayHttpArgs= [NSMutableArray array];
        //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onLoginSuccessed:) name:kNotificationLoginSuccess object:nil];
    }
    return self;
}

/**
 *  get请求
 *
 *  @param URLString  请求url
 *  @param parameters 请求参数
 *  @param success    请求结果回调
 */
- (void)get:(NSString *) URLString
 parameters:(NSDictionary *) parameters
    success:(void(^)(HttpResponse *response)) success{
    self.manager = [AFHTTPSessionManager manager];
    self.manager.requestSerializer = [AFJSONRequestSerializer serializer];
    self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [self.manager GET:URLString parameters:parameters progress:nil
              success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                  
                 
                  
                  NSError *err=nil;
                  
                  NSDictionary *resultDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&err];
                  
                  if (err) {
                      NSLog(@"解析失败 原因=%@",err.description);
                  }
                 
                  HttpResponse *model=[[HttpResponse alloc] initWithDictionary:resultDict];
                  if (success) {
                      success(model);
                  }

                  
              } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                  HttpResponse *model=[[HttpResponse alloc] initWithError:error];
                  if (success) {
                      success(model);
                  }
              }];
}

/**
 *  post请求
 *
 *  @param URLString  请求url
 *  @param parameters 请求参数
 *  @param success    请求结果回调
 */
- (void)post:(NSString *) URLString
  parameters:(NSDictionary *) parameters
     success:(void(^)(HttpResponse *response)) success {
    self.manager = [AFHTTPSessionManager manager];
    self.manager.requestSerializer = [AFJSONRequestSerializer serializer];
    self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [self.manager POST:URLString parameters:parameters progress:nil
               success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                   NSDictionary *resultDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
                   HttpResponse *model=[[HttpResponse alloc] initWithDictionary:resultDict];
                   if (success) {
                       success(model);
                   }
               } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                   HttpResponse *model=[[HttpResponse alloc] initWithError:error];
                   if (success) {
                       success(model);
                   }
               }];
}


/**
 *  http请求
 *
 *  @param args    请求对象
 *  @param success 请求成功回调
 */
- (void)requestWithHttpArgs:(HttpServerArgs *)args
                    success:(void(^)(HttpResponse *response)) success{
    
    
    
    args.requestFinishedBlock=success;
    
    //表示需要刷新token
    if ([self isNeedRefreshWithArgs:args]) {
        return;
    }
    

    if(args){
    
        if (args.httpWay==SCHW_Get) {
            [self get:args.urlString parameters:[args getRequestParams] success:success];
        }else if (args.httpWay==SCHW_Post){
            [self post:args.urlString parameters:[args getRequestParams] success:success];
        }
    }
}



/**
 *  http请求
 *
 *  @param httpWay    请求方式(get或post)
 *  @param method     请求的方法名
 *  @param parameters 请求参数
 *  @param success    请求成功回调
 */
- (void)requestWithHttpWayType:(SCHttpWay)httpWay
                    methodName:(NSString *)method
                    parameters:(NSDictionary *) parameters
                       success:(void(^)(HttpResponse *response)) success{
    
    HttpServerArgs *args=[[HttpServerArgs alloc] init];
    args.methodName=method;
    args.httpWay=httpWay;
    
    if (parameters&&[parameters count]>0) {
        [args addParamWithDictionary:parameters];
    }
   
    [self requestWithHttpArgs:args success:success];

}

/**
 *  http请求(默认请求方式为post)
 *
 *  @param method     请求的方法名
 *  @param parameters 请求参数
 *  @param success    请求成功回调
 */
- (void)requestWithMethodName:(NSString *)method
                   parameters:(NSDictionary *) parameters
                      success:(void(^)(HttpResponse *response)) success{
    HttpServerArgs *args=[[HttpServerArgs alloc] init];
    args.methodName=method;
    
    if (parameters&&[parameters count]>0) {
        [args addParamWithDictionary:parameters];
    }
    
     [self requestWithHttpArgs:args success:success];
}

/**
 *  单文件上传(默认为post请求)
 *
 *  @param method       请求的方法名
 *  @param parameters   请求参数
 *  @param uploadFile   上传的图片对象数据
 *  @param progress     上传进度
 *  @param success      请求成功回调
 */
- (void)uploadFileWithMethodName:(NSString *)method
                      parameters:(NSDictionary *) parameters
                      uploadFile:(uploadFileModel *)uploadFile
                        progress:(void(^)(float progress))progress
                         success:(void(^)(HttpResponse *response)) success{
    
    HttpServerArgs *args=[[HttpServerArgs alloc] init];
    args.methodName=method;
    
    if (parameters&&[parameters count]>0) {
        [args addParamWithDictionary:parameters];
    }
    
    args.requestFinishedBlock=success;
    
    //表示需要刷新token
    if ([self isNeedRefreshWithArgs:args]) {
        return;
    }
    
    
    if(args){
        
        self.manager = [AFHTTPSessionManager manager];
        self.manager.requestSerializer = [AFJSONRequestSerializer serializer];
        self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        
        NSURLSessionDataTask *task = [self.manager POST:args.urlString parameters:[args getRequestParams] constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            [formData appendPartWithFileData:uploadFile.imageData
                                        name:uploadFile.name
                                    fileName:uploadFile.fileName
                                    mimeType:uploadFile.mimeType];
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            if (progress) {
                progress(uploadProgress.fractionCompleted);
            }
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSDictionary *resultDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
            HttpResponse *model=[[HttpResponse alloc] initWithDictionary:resultDict];
            if (success) {
                success(model);
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
          
            HttpResponse *model=[[HttpResponse alloc] initWithError:error];
            if (success) {
                success(model);
            }
        }];
        
        [task resume];
       
    }

}

/**
 *  多文件上传(默认为post请求)
 *
 *  @param method       请求的方法名
 *  @param parameters   请求参数
 *  @param uploadFiles  多文件图片对象
 *  @param progress     上传进度
 *  @param success      请求成功回调
 */
- (void)uploadMultFilesWithMethodName:(NSString *)method
                           parameters:(NSDictionary *) parameters
                          uploadFiles:(NSArray <uploadFileModel*> *)uploadFiles
                             progress:(void(^)(float progress))progress
                              success:(void(^)(HttpResponse *response)) success{
    
    HttpServerArgs *args=[[HttpServerArgs alloc] init];
    args.methodName=method;
    
    if (parameters&&[parameters count]>0) {
        [args addParamWithDictionary:parameters];
    }
    
    args.requestFinishedBlock=success;
    
    //表示需要刷新token
    if ([self isNeedRefreshWithArgs:args]) {
        return;
    }
    
    
    if(args){
        
        self.manager = [AFHTTPSessionManager manager];
        self.manager.requestSerializer = [AFJSONRequestSerializer serializer];
        self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        
        NSURLSessionDataTask *task = [self.manager POST:args.urlString parameters:[args getRequestParams] constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            
            for (uploadFileModel *item in uploadFiles) {
                [formData appendPartWithFileData:item.imageData
                                            name:item.name
                                        fileName:item.fileName
                                        mimeType:item.mimeType];
            }
            
            
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            if (progress) {
                progress(uploadProgress.fractionCompleted);
            }
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            NSDictionary *resultDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
            HttpResponse *model=[[HttpResponse alloc] initWithDictionary:resultDict];
            if (success) {
                success(model);
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            HttpResponse *model=[[HttpResponse alloc] initWithError:error];
            if (success) {
                success(model);
            }
        }];
        
        [task resume];
        
    }

}


#pragma mark -私有方法
/**
 *  判断是否需要刷新token
 *
 *  @param args
 *
 *  @return  YES：表示需要  NO:表示不需要
 */
- (BOOL)isNeedRefreshWithArgs:(HttpServerArgs *)args{

    //表示已登录
    SystemUser *mod=[SystemUser shareInstance];
    if (mod.isLogin) {
        
        //判断请求token是否已过期
        if ([mod isExpiresAccessToken]) {
            
            
            [self.arrayHttpArgs addObject:args];
            
            //判断当前刷新token请求是否存在
            NSPredicate *per=[NSPredicate predicateWithFormat:@"SELF.methodName==%@",@"user/refresh_access_token"];
            NSArray *arr=[self.arrayHttpArgs filteredArrayUsingPredicate:per];
            if (arr&&[arr count]>0) {
                return YES;
            }
            
            NSLog(@"开始重新取得请求token");
            
            //重新获取token
            HttpServerArgs *httpArgs=[[HttpServerArgs alloc] init];
            httpArgs.methodName=@"user/refresh_access_token";
            httpArgs.httpWay=SCHW_Get;
            [httpArgs paramWithObjectsAndKeys:mod.userId,@"id",mod.refresh_token,@"refresh_token", nil];
            
            //添加
            [self.arrayHttpArgs addObject:httpArgs];
            
            [self get:httpArgs.urlString parameters:[httpArgs getRequestParams] success:^(HttpResponse *response) {
                
                NSLog(@"重新取得请求token完成 =%@",response.responseData);
                
                //移除
                [self.arrayHttpArgs removeObject:httpArgs];
                
                if (response.success) { //请求成功
                    
                    NSDictionary *dic=(NSDictionary *)response.responseData;
                    
                    mod.access_token=[dic objectForKey:@"access_token"];
                    mod.expires_in=[NSString stringWithFormat:@"%@",[dic objectForKey:@"expires_in"]];
                    [mod saveUser]; //重新保存
                    [mod saveExpiresDate]; //保存登录过期时间
                    
                    //替换访问请求的token参数
                    for (HttpServerArgs *item in self.arrayHttpArgs) {
                        
                        [item replaceParamWithKey:@"access_token" paramValue:mod.access_token];
                        
                        if (item.httpWay==SCHW_Get) {
                            [self get:args.urlString parameters:[args getRequestParams] success:args.requestFinishedBlock];
                        }else if (item.httpWay==SCHW_Post){
                            [self post:args.urlString parameters:[args getRequestParams] success:args.requestFinishedBlock];
                        }
                    }
                    //移除所有
                    [self.arrayHttpArgs removeAllObjects];
                }
                
            }];
            
            
            return YES;
        }
        
    }
    
    return NO;
}



- (void)onLoginSuccessed:(NSNotification *) note {
    @synchronized (self) {
        NSMutableArray *tempArray = [self.arrayRequest copy];
        for (int i = 0; i < [tempArray count]; ++i) {
            RequestBlock item = [tempArray objectAtIndex:i];
            item();
            [self.arrayRequest removeObject:item];
        }
    }
}



@end
